from django.shortcuts import render_to_response
from django.template import RequestContext
from myproject.auth.models import AbstractUser, Student, Teacher, Institute, Update, ConnectionRequest, Review,\
    Photo, Slot, SlotForm
from PIL import Image
from forms import UploadImageForm
import re, datetime
import os
from django.core.files.images import ImageFile
from myproject.settings import STATIC_URL

def viewProfile(request, profileOwner, abstract_user_id, updates_type, updates_len=10): 
    print AbstractUser.objects.get(user=request.user).messages_notification
    loggedinUser = getUser(request.user, False)   
    if abstract_user_id:
        friend = getUser(AbstractUser.objects.get(pk=abstract_user_id), True)
        currentUser = friend
    else:
        currentUser = loggedinUser
    
    profileOwner, my_teachers, my_institutes, requestedFriend, friendRequested, areFriends, requestedWork, workRequested, areConnected = tab_data(request, currentUser, abstract_user_id)
    print areConnected
    if currentUser.category == 'institute':
        my_teachers = currentUser.teacher_set.all()
        my_institutes = None
    elif currentUser.category == 'teacher':
        my_institutes = currentUser.work_institutes.all()
        my_teachers = None
    else:
        my_teachers = None
        my_institutes = None
    
    if updates_type == 'other':
        updates = currentUser.abstract_user.user.update_set.filter(other=True).order_by('-pub_date')
    elif updates_type == 'fav':
        updates = currentUser.abstract_user.user.update_set.filter(fav=True).order_by('-pub_date')
    else:
        updates = currentUser.abstract_user.user.update_set.order_by('-pub_date')
    if len(updates) > updates_len:
        updates = updates[0:updates_len]
        more_updates_available = True
    else:
        more_updates_available = False 
    
    '''PROFILE PHOTO'''
    if currentUser.category != 'institute':
        photo = currentUser.photo
    else:
        photo = currentUser.logo
    
    # Add review count to updates
    updates_and_review_count = []
    for update in updates:
        count = len(Review.objects.filter(media=update))
        updates_and_review_count.append((update, count))
    
    return render_to_response('myprofile/profile.html', {'loggedinUser':loggedinUser, 'currentUser':currentUser, 'updates':updates_and_review_count, 
                                                        'profileOwner':profileOwner, 'friendRequested':friendRequested, 'requestedFriend':requestedFriend, 
                                                        'areFriends':areFriends, 'my_teachers':my_teachers, 'my_institutes':my_institutes,
                                                        'requestedWork':requestedWork, 'workRequested':workRequested, 'areConnected':areConnected,
                                                        'photo':photo, 'more_updates_available':more_updates_available,
                                                        'updates_type':updates_type},
                              context_instance=RequestContext(request))

''' 
author: Nader
date: S1
desc: Takes the user to their profile
'''
def profile(request):
    from myproject.admins.views import admin
    if request.user.is_superuser:
        return admin(request)
    else:
        return viewProfile(request, profileOwner=True, abstract_user_id=None, updates_type='all')
    
def viewOtherProfile(request, abstract_user_id):
    return viewProfile(request, False, abstract_user_id, 'all')

'''
author: Nader
date: 01.03.2012
desc: Takes an object of type User/AbstractUser and returns its Student/Teacher/Institute
'''
def getUser(user, abstract):
    if abstract: # checks whether the given user is an AbstractUser or User
        institute = Institute.objects.filter(abstract_user=user)
        student = Student.objects.filter(abstract_user=user)
        teacher = Teacher.objects.filter(abstract_user=user)
    else:
        institute = Institute.objects.filter(abstract_user=AbstractUser.objects.get(user=user))
        student = Student.objects.filter(abstract_user=AbstractUser.objects.get(user=user))
        teacher = Teacher.objects.filter(abstract_user=AbstractUser.objects.get(user=user))
    
    if institute:
        currentUser = institute[0]
    elif student:
        currentUser = student[0]
    elif teacher:
        currentUser = teacher[0]
   
    return currentUser

'''
author: Nader
date: S1
desc: Posts an update for any user and saves it then reloads their profile
modified on 06.04.12: Fixed a bug in posting youtube videos and improved the regexs
'''
def postUpdate(request):
    entry = request.POST['entry']
    
    if entry.__contains__("youtube.com") or entry.__contains__("youtu.be"):    
        if entry.__contains__("youtube.com"):
            if re.match('.*&*v=.*&.*', entry):
                video_id = re.sub('.*&*v=(.*?)&.*', r'\1', entry)
            else:
                video_id = re.sub('.*&*v=(.*)$', r'\1', entry)
        elif entry.__contains__("youtu.be"):
            video_id = re.sub(".*.be/(.*)$", r'\1', entry)
        update = Update(owner=request.user, pub_date=datetime.datetime.now(), video_id=video_id)
    
    elif entry.__contains__('soundcloud'):
        if re.match('.*object.*param.*param.*embed.*embed.*object.*span.*span.*', 
                    entry):
            mp3_url = re.sub(".*value=\"(.*)\"></param>\s<param.*", r'''\1''', entry)
            mp3_name = re.sub(".*<span>(.*)</span>.*", r'''\1''', entry)
            mp3_name = re.sub("<a href.*>(.*)</a>(.*)<a href.*>(.*)</a>", r'''\1\2\3''', mp3_name)
            mp3_name = re.sub("<a href.*>(.*)</a>", r'''\1''', mp3_name)
            print mp3_url
            update = Update(owner=request.user, pub_date=datetime.datetime.now(), mp3_url=mp3_url, mp3_name=mp3_name)
        else:
            return profile(request)
        
    else: #if Text
        '''
        content = ''
        while len(entry) > 57:
            content += entry[0:57] + '<br/>'
            entry = entry[57:len(entry)]
        content += entry
        while len(content) < 57:
            content += '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
        '''
        content=entry
        update = Update(owner=request.user, pub_date=datetime.datetime.now(), content=content)
    if entry:
        # If <other> is checked, then set it to True
        try:
            other = request.POST['other']
            update.other = True
        except KeyError:
            other = ''

        if other:
            update.other = True
        # If <fav> is checked, then set it to True
        try:
            fav = request.POST['fav']
        except KeyError:
            fav = ''
        if fav:
            update.fav = True
        
        update.admin_update = request.user.is_superuser
        update.save()
        
    return profile(request)

'''
author: Nader Alexan
date: 21.03.12
desc: Allow user to delete an update, however prevet the possiblity of deleting an update s/he doesn't own by manipulating the url. Also, handle refreshing
'''
def deleteUpdate(request, update_id):
    try: update = Update.objects.get(pk=update_id)
    except: return profile(request)
    if update.owner == request.user:
        update.delete()
    return profile(request)

'''
author: Nader
date: 01.03.2012
desc: Previews a list of the User's friends
'''    
def displayConnections(request, abstract_user_id):
    abstract_user = AbstractUser.objects.get(pk=abstract_user_id)
    currentUser = getUser(abstract_user, abstract=True)
    loggedInUser = getUser(request.user, abstract=False)
    profileOwner = loggedInUser == currentUser

    friendRequests = []
    for fr in ConnectionRequest.objects.filter(receiver=abstract_user, category='friend'):
        current =  getUser(fr.sender, abstract=True)
        if current.category == 'institute':
            friendRequests.append((fr,current.logo))
        else:
            friendRequests.append((fr,current.photo))
    
    employmentRequests = []
    for er in ConnectionRequest.objects.filter(receiver=abstract_user, category='work'):
        current =  getUser(er.sender, abstract=True)
        if current.category == 'institute':
            employmentRequests.append((er, current.logo))
        else:
            employmentRequests.append((er, current.photo))

    friends = []
    for f in abstract_user.friends.all():
        current = getUser(f, abstract=True)        
        if current.category == 'institute':
            friends.append((f,current.logo))
        else:
            friends.append((f,current.photo))

    employment = []
    if currentUser.category == 'teacher':
        for emp in currentUser.work_institutes.all():
            current = getUser(emp.abstract_user, abstract=True)        
            if current.category == 'institute':
                employment.append((emp,current.logo))
            else:
                employment.append((emp,current.photo))        
    elif currentUser.category == 'institute':
        for emp in currentUser.teacher_set.all():
            current = getUser(emp.abstract_user, abstract=True)        
            if current.category == 'institute':
                employment.append((emp,current.logo))
            else:
                employment.append((emp,current.photo))

    requestedFriend, friendRequested, areFriends = None, None, None

    if profileOwner:
        loggedInUser.abstract_user.connections_notification = 0
        loggedInUser.abstract_user.save()
    else:
        viewer_abstract_user = AbstractUser.objects.get(user=request.user)
        viewee_abstract_user = AbstractUser.objects.get(pk=abstract_user_id)
        requestedFriend, friendRequested, areFriends = checkFriendship(viewer_abstract_user, viewee_abstract_user)
        
    return render_to_response('myprofile/friends.html', {'loggedinUser':getUser(request.user, False),'friends':friends,
                                                         'employment':employment,
                                                        'user':request.user, 'currentUser':currentUser, 
                                                        'friendRequests':friendRequests, 'employmentRequests':employmentRequests,
                                                        'profileOwner':profileOwner, 'requestedFriend':requestedFriend, 
                                                        'friendRequested':friendRequested, 'areFriends':areFriends}, 
                              context_instance=RequestContext(request)) 

'''
author: Nader Alexan
date: 14.04.12
desc: retrived friendship data for two users
'''
def checkFriendship(viewer_abstract_user, viewee_abstract_user):
    # I already asked to be this User's friend
    requestedFriend = ConnectionRequest.objects.filter(sender=viewer_abstract_user, receiver=viewee_abstract_user, category='friend')
    # This User is requesting to be my friend
    friendRequested = ConnectionRequest.objects.filter(receiver=viewer_abstract_user, sender=viewee_abstract_user, category='friend')
    # check if they are friends
    areFriends = viewer_abstract_user.friends.all().__contains__(viewee_abstract_user)
    return requestedFriend, friendRequested, areFriends

'''
author: Nader
date: 02.03.2012
desc: Send a friends request from the current user to another user
'''
def sendFriendRequest(request, abstract_user_id):
    return sendConnectionRequest(request, abstract_user_id, category='friend')
    
'''
author: Nader
date: 03.03.2012
desc: Accept friend request and add friend to friends list
'''
def acceptFriendRequest(request, abstract_user_id):
    return acceptConnectionRequest(request, abstract_user_id, category='friend')

'''
author: Nader
date: 03.03.2012
desc: Accept friend request and add friend to friends list
'''
def rejectFriendRequest(request, abstract_user_id):
    return rejectConnectionRequest(request, abstract_user_id, category='friend')

def sendEmploymentRequest(request, abstract_user_id):
    return sendConnectionRequest(request, abstract_user_id, category='work')
    
def acceptEmploymentRequest(request, abstract_user_id):
    return acceptConnectionRequest(request, abstract_user_id, category='work')

def rejectEmploymentRequest(request, abstract_user_id):
    return rejectConnectionRequest(request, abstract_user_id, category='work')

def sendConnectionRequest(request, abstract_user_id, category):
    sender = AbstractUser.objects.get(user=request.user)
    receiver = AbstractUser.objects.get(pk=abstract_user_id)
    receiver.connections_notification += 1
    receiver.save()
    if not ConnectionRequest.objects.filter(sender=sender, receiver=receiver, category=category):
        friend_request =  ConnectionRequest(sender=sender, receiver=receiver, category=category)
        friend_request.save()
    return viewOtherProfile(request, abstract_user_id)

def acceptConnectionRequest(request, abstract_user_id, category):
    sender = AbstractUser.objects.get(pk=abstract_user_id)
    receiver = AbstractUser.objects.get(user=request.user)
    # delete the friend request
    try: ConnectionRequest.objects.get(sender=sender, receiver=receiver, category=category).delete()
    except: pass
    if category == 'friend':
        # add to friend list
        receiver.friends.add(sender)
    else:
        receiver = getUser(receiver.id, True)
        if receiver.category == 'teacher':
            receiver.work_institutes.add(getUser(sender, True))
        else:
            receiver.teacher_set.add(getUser(sender, True))
    return displayConnections(request, AbstractUser.objects.get(user=request.user).id)

def rejectConnectionRequest(request, abstract_user_id, category):
    sender = AbstractUser.objects.get(pk=abstract_user_id)
    receiver = AbstractUser.objects.get(user=request.user)
    # delete the friend request
    ConnectionRequest.objects.get(sender=sender, receiver=receiver, category=category).delete()
    
    return displayConnections(request)

'''
author: Nader
date: 04.03.2012
desc: Display reviews and allow posting of new reviews

modified: 14.04.12 
1.added the passing of review questions to profile.html
2.added a success_message for use when a new question is added successfully
'''
def reviews(request, abstract_user_id, add_success_message=None, del_success_message=None, review_success_message=None, media=None, reviews_len=10):
    reviewer = AbstractUser.objects.get(user=request.user)
    reviewee = AbstractUser.objects.get(pk=abstract_user_id)    
    
    reviews = []
    for review in Review.objects.filter(reviewee=reviewee).order_by('-date'):
        current = getUser(review.reviewer, abstract=True)
        if current.category == 'institute':
            reviews.append((review, current.logo))
        else:
            reviews.append((review, current.photo))

    if reviewer == reviewee:
        reviewer.reviews_notification = 0
        reviewer.save()
    
    currentUser = getUser(reviewee, True)
    profileOwner, my_teachers, my_institutes, requestedFriend, friendRequested, areFriends, requestedWork, workRequested, areConnected = tab_data(request, currentUser, abstract_user_id)
     
    # get review questions
    try: questions = reviewee.questionnaire.question_set.all()
    except: questions = []
    
    # if currently this user has more reviews than the length that should be shown on the page, limit them
    if len(reviews) > reviews_len: 
        reviews = reviews[0:reviews_len]
        more_reviews_available = True
    else:
        more_reviews_available = False
    
    return render_to_response('myprofile/reviews.html', {'reviews':reviews,
                                                        'loggedinUser':getUser(request.user, False),
                                                        'currentUser':currentUser, 
                                                        'profileOwner':profileOwner, 
                                                        'my_teachers':my_teachers, 
                                                        'my_institutes':my_institutes, 
                                                        'requestedFriend':requestedFriend, 
                                                        'friendRequested':friendRequested, 
                                                        'areFriends':areFriends, 
                                                        'requestedWork':requestedWork, 
                                                        'workRequested':workRequested, 
                                                        'areConnected':areConnected,
                                                        'questions':questions,
                                                        'add_success_message':add_success_message,
                                                        'del_success_message':del_success_message,
                                                        'review_success_message':review_success_message,
                                                        'media':media,
                                                        'more_reviews_available':more_reviews_available}, 
                              context_instance=RequestContext(request))
    
'''
author: Nader
date: 04.03.2012
desc: Post a review and reloads page

modified: 14.04.12
added questionnaire for student
'''
def postReview(request, abstract_user_id, media=None):
    # To avoid url manipulation, check that there actually is data being posted
    if request.method != 'POST':
        return reviews(request, abstract_user_id)
    from myproject.auth.models import Thread, MSG, ThreadNotification
    reviewee = AbstractUser.objects.get(pk=abstract_user_id)    
    reviewer = AbstractUser.objects.get(user=request.user)
    content = request.POST['content']
    
    # the reason for not media is because all media reviews have to be public
    if getUser(reviewee, abstract=True).category == 'student' and not media:
        try: questions = reviewee.questionnaire.question_set.all()
        except: questions = []
        questionnaire = ''
        for question in questions:
            response = request.POST['question_' + str(question.id)]
            if response:
                questionnaire += '<b>'+question.content+'</b><br/>' + response + '<br/><br/>'
        content = questionnaire + content

        category = request.POST['category']
        if category == 'private' and content:
            # Check if review already available incase the user is just refreshing the page
            try: MSG.objects.get(content='<br/><br/>'+content, sender=reviewer)
            except:
                thread = Thread(category='private review', subject='Private Review', date_started=datetime.datetime.now(), admin=False)
                thread.save()
                thread.receivers.add(reviewer)
                thread.receivers.add(reviewee)
                thread.save()
                ThreadNotification(thread=thread, abstract_user=reviewer, notifications=0).save()
                ThreadNotification(thread=thread, abstract_user=reviewee, notifications=1).save()
                reviewee.messages_notification += 1
                reviewee.save()
                
                message = MSG(thread=thread, content='<br/><br/>'+content, sender=reviewer, date_sent=datetime.datetime.now())
                message.save()
            return reviews(request, abstract_user_id, review_success_message='The private review has been sent successfully, you can check it in your messages')
        
    review_success_message = None        
    if content:
        date = datetime.datetime.now()
        # Check if review already available incase the user is just refreshing the page
        try: Review.objects.get(reviewee=reviewee, reviewer=reviewer, content=content)
        except: 
            review = Review(reviewee=reviewee, reviewer=reviewer, content=content, date=date, report_count=0, media=media)
            review.save()
            reviewee.reviews_notification += 1
            reviewee.save()
            
            review_success_message='The public review has been sent successfully, you can check it below'
            currentUser = getUser(reviewee, abstract=True)
            currentUser.reviews += 1
            currentUser.save()
    return reviews(request, abstract_user_id, review_success_message=review_success_message)

def uploadImage(request):
    if request.method == 'POST':
        form = UploadImageForm(request.POST, request.FILES)
        
        if form.is_valid():
            return handle_uploaded_image(request)
    else:
        form = UploadImageForm()
    
    '''PROFILE PHOTO'''
    currentUser = getUser(request.user, False)
    if currentUser.category == 'institute':
        photo = currentUser.logo
    else:
        photo = currentUser.photo
    if photo != None:      
        path = photo.path
    else:
        path = None
        
    return render_to_response('myprofile/uploadImage.html', {'loggedinUser':currentUser,
                                                             'form': form, 'currentUser':currentUser,
                                                             'profileOwner':True,
                                                             'photoPath':path},
                              context_instance=RequestContext(request))    

def handle_uploaded_image(request):
    # Get photo dimentions
    image_file = request.FILES['image_file']
    if int(image_file.size) > 2500000:
        return render_to_response('myprofile/uploadImage.html', {'loggedinUser':getUser(request.user, False),
                                                                 'profileOwner':True,
                                                                 'currentUser':getUser(request.user, False),
                                                                 'form': UploadImageForm(request.POST, request.FILES),
                                                                 'error_message':'File is too large, please upload a photo smaller than 2.5 MB'},
                              context_instance=RequestContext(request))
    width = ImageFile(image_file).width
    height = ImageFile(image_file).height

    path = '/home/ysna/webapps/bomtak_static/uploaded/' + request.user.username + '.jpg'
    
    i = Image.open(image_file)
    # Save as a file
    i.save(path)
    
    # Open
    imagef  = Image.open(path)
    if imagef.mode not in ('L', 'RGB'):
            imagef = imagef.convert('RGB')
    # Resize
    imagef = imagef.resize(scale_dimensions(width, height, 300), Image.ANTIALIAS)
    # Resave
    imagef.save(path)
    
    # Assign to user
    photo = Photo(path=STATIC_URL + '/uploaded/' + request.user.username + '.jpg')
    photo.save()
    
    currentUser = getUser(request.user, False)
    if currentUser.category != 'institute':
        currentUser.photo = photo
    else:
        currentUser.logo = photo
    currentUser.save()
    return profile(request)

def scale_dimensions(width, height, longest_side):
    if width > height:
        if width > longest_side:
            ratio = longest_side*1./width
            return (int(width*ratio), int(height*ratio))
    elif height > longest_side:
        ratio = longest_side*1./height
        return (int(width*ratio), int(height*ratio))
    return (width, height)

'''
author: Nader Alexan
date: 15.04.12
desc: Allow an institute to delete one of their photos
'''
def deletePhoto(request, photo_id):
    Photo.objects.get(pk=photo_id).delete()
    del_success_message = 'Photo has been deleted successfully'
    return photos(request, AbstractUser.objects.get(user=request.user).id, del_success_message=del_success_message)

'''
author: Nader Alexan
date: 15.04.12
desc: send data required to photos.html
'''
def photos(request, abstract_user_id, del_success_message=None, add_success_message=None, error_message=None, form=UploadImageForm()):
    currentUser = getUser(AbstractUser.objects.get(pk=abstract_user_id), abstract=True)
    photoPaths = [photo.path for photo in currentUser.photo_set.all()]
    
    if currentUser.logo:
        logoPath = currentUser.logo.path
    else:
        logoPath = None

    profileOwner, my_teachers, my_institutes, requestedFriend, friendRequested, areFriends, requestedWork, workRequested, areConnected = tab_data(request, currentUser, abstract_user_id)
    
    return render_to_response('myprofile/photos.html', {'loggedinUser':getUser(request.user, False),
                                                        'currentUser':currentUser, 
                                                        'form':form,
                                                        'photoPaths':photoPaths,
                                                        'logoPath':logoPath,
                                                        'photos':currentUser.photo_set.all(),
                                                        'del_success_message':del_success_message,
                                                        'add_success_message':add_success_message,
                                                        'error_message':error_message,
                                                        'profileOwner':profileOwner, 
                                                        'my_teachers':my_teachers, 
                                                        'my_institutes':my_institutes, 
                                                        'requestedFriend':requestedFriend, 
                                                        'friendRequested':friendRequested, 
                                                        'areFriends':areFriends, 
                                                        'requestedWork':requestedWork, 
                                                        'workRequested':workRequested, 
                                                        'areConnected':areConnected}, 
                              context_instance=RequestContext(request))

def tab_data(request, currentUser, abstract_user_id):
    loggedinUser = getUser(request.user, abstract=False)
    profileOwner = currentUser==loggedinUser

    if currentUser.category == 'institute':
        my_teachers = currentUser.teacher_set.all()
        my_institutes = None
    elif currentUser.category == 'teacher':
        my_institutes = currentUser.work_institutes.all()
        my_teachers = None
    else:
        my_teachers = None
        my_institutes = None

    if profileOwner:
        requestedFriend, friendRequested, areFriends = None, None, None
        requestedWork, workRequested, areConnected = None, None, None
    else:
        viewer_abstract_user = AbstractUser.objects.get(user=request.user)
        viewee_abstract_user = AbstractUser.objects.get(pk=abstract_user_id)

        requestedFriend, friendRequested, areFriends = checkFriendship(viewer_abstract_user, viewee_abstract_user)


        possibleEmployment = getUser(request.user, False).category != currentUser.category
        
        # check if you are a teacher/institute checking the profile of an institute/teacher
        if currentUser.category != 'student' and loggedinUser.category != 'student' and possibleEmployment:
            # I already requested a work connection with this user
            requestedWork = ConnectionRequest.objects.filter(sender=viewer_abstract_user, receiver=viewee_abstract_user, category='work')
            # This user is requesting a work connection with me
            workRequested = ConnectionRequest.objects.filter(receiver=viewer_abstract_user, sender=viewee_abstract_user, category='work')
            # check if they are connected
            if currentUser.category == 'teacher':
                areConnected = currentUser.work_institutes.all().__contains__(getUser(request.user, False))
            else:
                areConnected = getUser(request.user, False).work_institutes.all().__contains__(currentUser)
        else:
            requestedWork, workRequested, areConnected = None, None, None
    return (profileOwner, my_teachers, my_institutes, requestedFriend, friendRequested, areFriends, requestedWork, workRequested, areConnected)

def addPhoto(request):
    form = UploadImageForm(request.POST, request.FILES)
    if form.is_valid():
        return handle_uploaded_image2(request)
    else:
        return photos(request, AbstractUser.objects.get(user=request.user).id, form=form)

def handle_uploaded_image2(request):
    # Get photo dimentions
    image_file = request.FILES['image_file']
    
    abstract_user_id = AbstractUser.objects.get(user=request.user).id
    if int(image_file.size) > 2500000:
        return photos(request, abstract_user_id, form=UploadImageForm(request.POST, request.FILES), error_message='File is too large, please upload a photo smaller than 2.5 MB')
        
    width = ImageFile(image_file).width
    height = ImageFile(image_file).height
    SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
    
    currentUser = getUser(request.user, abstract=False)
    photo = Photo(institute=currentUser, caption=request.POST['caption'])
    photo.save()
    
    path = '/home/ysna/webapps/bomtak_static/uploaded/' + request.user.username + str(photo.id) + '.jpg'
    
    # Save as a file
    Image.open(request.FILES['image_file']).save(path)
    
    # Open
    imagef  = Image.open(path)
    if imagef.mode not in ('L', 'RGB'):
            imagef = imagef.convert('RGB')
    # Resize
    imagef = imagef.resize(scale_dimensions(width, height, 600), Image.ANTIALIAS)
    # Resave
    imagef.save(path)
    
    # Assign to user
    photo.path = STATIC_URL + 'uploaded/' + request.user.username + str(photo.id) + '.jpg'
    photo.save()
    
    return photos(request, abstract_user_id, add_success_message='Photo added successfuly, scroll down to check it out :)')
    
'''
author: Nader
date: 06.03.2012
desc: Show only My Jams/Lessons/Talent updates in the profile
'''
def showOther(request, abstract_user_id):
    return viewProfile(request, False, abstract_user_id, 'other')

'''
author: Nader
date: 06.03.2012
desc: Show only Favorite updates in the profile
'''
def showFavorites(request, abstract_user_id):
    return viewProfile(request, False, abstract_user_id, 'fav')    

'''
SCHEDULES
author: Nader
Start: 18.03.12
Implemented:
'''
def addSlot(request):
    def convertTo24Hr(time):
        if time == '12:00 pm':
            return '12:00'
        elif re.match(r'12:\d+\sam', time):
            return '00' + re.sub(r'12(:\d+\s)am', r'\1', time)
        elif re.match(r'\d+:\d+\sam', time): 
            return re.sub(r'(\d+:\d+)\sam', r'\1', time)
        else:
            hrs = int(re.sub(r'(\d+):\d+\spm', r'\1', time))
            mins = int(re.sub(r'\d+:(\d+)\spm', r'\1', time))
            hrs += 12
            return str(hrs) + ':' + str(mins)
    error_message, success_slot, conflict_slot = None, None, None
    if request.method == 'POST':
        form = SlotForm(request.POST)
        if form.is_valid():
            # Save slot
            title = form.cleaned_data['title']
            start = form.cleaned_data['start']
            end = form.cleaned_data['end']
            day = form.cleaned_data['day']
            location = form.cleaned_data['location']
            abstract_user = AbstractUser.objects.get(user=request.user)
            
            if convertTo24Hr(end) <= convertTo24Hr(start):
                error_message = 'End time must be after start time'
            else:
                slots = abstract_user.slot_set.all()
                '''Uncomment to allow the alogrithem to check for overlapping slots
                for slot in slots:
                    if day == slot.day and (convertTo24Hr(start) >= convertTo24Hr(slot.start) and convertTo24Hr(start) <= convertTo24Hr(slot.end) or 
                                            convertTo24Hr(end) > convertTo24Hr(slot.start) and convertTo24Hr(end) < convertTo24Hr(slot.end)):
                        error_message = 'This slot is in conflict with: '
                        conflict_slot = slot
                        break
                '''
                if not error_message and not conflict_slot: 
                    if not title:
                        title = 'No title'
                    success_slot = Slot(abstract_user=abstract_user, title=title, start=start, end=end, day=day, location=location)
                    success_slot.save()
                    '''
                    success_message = 'A new slot has been successfully added to your schedule with the following info: '
                    if title:
                        success_message += ' ' + title
                    success_message += ' ' + start    
                    success_message += ' - ' + end
                    if location:
                        success_message += ' @ ' + location
                    '''
    
    # Get user info
    currentUser = getUser(request.user, False)
    
    path = None
    if currentUser.category != 'institute':
        photo = currentUser.photo
    else:
        photo = currentUser.logo
    
    if photo != None:      
        path = photo.path
    
    week = getSchedule(AbstractUser.objects.get(user=request.user).id)
    return render_to_response('myprofile/addSlot.html', {'loggedinUser':getUser(request.user, False),
                                                         'profileOwner':True,
                                                         'currentUser':currentUser, 'photoPath':path,
                                                         'conflict_slot':conflict_slot, 'error_message':error_message,
                                                         'success_slot':success_slot, 'form':SlotForm(), 
                                                         'sun':week[0], 'mon':week[1], 'tue':week[2],
                                                         'wed':week[3], 'thurs':week[4], 'fri':week[5],
                                                         'sat':week[6]},
                              context_instance=RequestContext(request))   

def viewSchedule(request, abstract_user_id):
    week = getSchedule(abstract_user_id)
    loggedinUser = getUser(request.user, False)
    currentUser = getUser(AbstractUser.objects.get(pk=abstract_user_id), abstract=True)

    profileOwner, my_teachers, my_institutes, requestedFriend, friendRequested, areFriends, requestedWork, workRequested, areConnected = tab_data(request, currentUser, abstract_user_id)

    path = None
    if currentUser.category != 'institute':
        photo = currentUser.photo
    else:
        photo = currentUser.logo

    return render_to_response('myprofile/schedule.html', {'loggedinUser':loggedinUser,
                                                          'profileOwner':profileOwner,
                                                          'currentUser':currentUser, 
                                                         'sun':week[0], 'mon':week[1], 'tue':week[2],
                                                         'wed':week[3], 'thurs':week[4], 'fri':week[5],
                                                         'sat':week[6],
                                                         'requestedFriend':requestedFriend, 
                                                        'friendRequested':friendRequested, 
                                                        'areFriends':areFriends,
                                                        'my_teachers':my_teachers,
                                                        'my_institutes':my_institutes,
                                                        'photo':photo},
                              context_instance=RequestContext(request))

def getSchedule(abstract_user_id):
    abstract_user = AbstractUser.objects.get(pk=abstract_user_id)
    slots = abstract_user.slot_set.all().order_by('-start')
    sat, sun, mon, tue, wed, thurs, fri = [], [], [], [], [], [], []
    for slot in slots:
        if slot.day == 'Saturday':
            sat.append(slot)
        elif slot.day == 'Sunday':
            sun.append(slot)
        elif slot.day == 'Monday':
            mon.append(slot)
        elif slot.day == 'Tuesday':
            tue.append(slot)
        elif slot.day == 'Wednesday':
            wed.append(slot)
        elif slot.day == 'Thursday':
            thurs.append(slot)
        else:
            fri.append(slot)
    return [sun, mon, tue, wed, thurs, fri, sat]

def getUpdated(request):
    current = Update.objects.filter(admin_update=True)
    friends = AbstractUser.objects.get(user=request.user).friends.all()
    for friend in friends:
        current |= Update.objects.filter(owner=friend.user)
    
    currentUser = getUser(request.user, abstract=False)

    if currentUser.category == 'institute':
        for emp in currentUser.teacher_set.all():
            current |= Update.objects.filter(owner=emp.abstract_user.user) 
    elif currentUser.category == 'teacher':       
        for emp in currentUser.work_institutes.all():
            current |= Update.objects.filter(owner=emp.abstract_user.user)

    updates = []
    if current:
        for update in current.order_by('-pub_date'):
            if update.admin_update:
                updates.append(('admin', update))
            else:
                updates.append((AbstractUser.objects.get(user=update.owner), update))


    most_reviewed = getMostReviewed()
    return render_to_response('myprofile/getUpdated.html', {'loggedinUser':getUser(request.user, False),
                                                            'updates':updates,
                                                            'most_reviewed':most_reviewed,
                                                            'students':Student.objects.filter(HOF=True),
                                                            'teachers':Teacher.objects.filter(HOF=True),
                                                            'institutes':Institute.objects.filter(HOF=True),
                                                            'currentUser':currentUser,
                                                            'profileOwner':True},
                              context_instance=RequestContext(request))
    
'''
author: Nader Alexan
date: 11.04.12
desc: report a review                        
'''
def reportReview(request, review_id, abstract_user_id):
    review = Review.objects.get(pk=review_id)
    review.report_count += 1
    review.save()
    return reviews(request, abstract_user_id)

'''
author: Nader Alexan
date: 14.04.12
desc: Allow a student to add question for his/her review form
'''
def addReviewQuestion(request):
    from myproject.auth.models import Questionnaire, Question
    content = request.POST['content']
    abstract_user = AbstractUser.objects.get(user=request.user)
    try: questionnaire = abstract_user.questionnaire
    except: 
        questionnaire = Questionnaire(abstract_user=abstract_user)
        questionnaire.save()
    Question(content=content, questionnaire=questionnaire).save()
    add_success_message = 'The question: "' + content + '" has been added successfully'
    return reviews(request, abstract_user.id, add_success_message=add_success_message)  
    
'''
author: Nader Alexan
date: 14.04.12
desc: Allow student to delete one of the questions
'''
def deleteReviewQuestion(request, question_id):
    from myproject.auth.models import Question
    question = Question.objects.get(pk=question_id)
    question.delete()
    del_success_message = 'The question "' + question.content + '" has been deleted successfully'
    return reviews(request, AbstractUser.objects.get(user=request.user).id, del_success_message=del_success_message)

'''
author: Nader Alexan
date: 06.05.12
desc: Allow a user to change their password
'''
def changePassword(request):
    from myproject.auth.views import changePassword
    return changePassword(request, 'myprofile/changePassword.html')
'''
author: Nader and Joe
date: 3.6.12
desc: Generate a list of user to be sent to the hall of fame according to some algorithm that is yet to be implemented    
TODO: implement the algorithm
'''
def getMostReviewed():
    # Get the 2 most reviewed teachers, insititues, students
    most_reviewed = []
    teachers = Teacher.objects.all().order_by('-reviews')
    if teachers:
        most_reviewed.append(teachers[0].abstract_user)
    students = Student.objects.all().order_by('-reviews')
    if students:
        most_reviewed.append(students[0].abstract_user)
    institutes = Institute.objects.all().order_by('-reviews')
    if institutes:
        most_reviewed.append(institutes[0].abstract_user)
    return most_reviewed

'''
author: Nader
date: 1.7.12
desc: Allow user to review video/audio
'''
def reviewVidOrAud(request, update_id, abstract_user_id):
    return reviews(request, abstract_user_id, media=Update.objects.get(pk=update_id))

def postMediaReview(request, abstract_user_id, media_id):
    return postReview(request, abstract_user_id, Update.objects.get(pk=media_id))

def viewMediaReviews(request, update_id):
    update = Update.objects.get(pk=update_id)
    reviews = Review.objects.filter(media=update)
    areFriends = AbstractUser.objects.get(user=request.user).friends.all().__contains__(AbstractUser.objects.get(user=update.owner))
    return render_to_response('myprofile/mediaReviews.html', {'loggedinUser':getUser(request.user, False),
                                                         'currentUser':getUser(update.owner, False), 
                                                         'profileOwner':getUser(request.user, False)==getUser(update.owner, False),
                                                         'media':update,
                                                         'areFriends':areFriends,
                                                         'reviews':reviews,}, 
                              context_instance=RequestContext(request))

def viewMoreUpdates(request, updates_type, abstract_user_id, updates_len):
    abstract_user_id, updates_len  = int(abstract_user_id), int(updates_len)
    profileOwner = abstract_user_id == AbstractUser.objects.get(user=request.user).id
    return viewProfile(request, profileOwner, abstract_user_id, updates_type, updates_len=updates_len+10)

def viewMoreReviews(request, abstract_user_id, reviews_len):
    abstract_user_id, reviews_len  = int(abstract_user_id), int(reviews_len)
    return reviews(request, abstract_user_id, reviews_len=reviews_len+10)
